package com.example.md.filter;


import com.example.md.common.Result;
import com.example.md.dto.user.LoginStatus;
import com.fasterxml.jackson.databind.ObjectMapper;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Set;
import java.util.HashSet;

@Component
@Order(10)
public class TokenFilter extends OncePerRequestFilter {

    private final ObjectMapper objectMapper = new ObjectMapper();

    // 定义白名单路径，不需要校验token
    private static final Set<String> WHITE_LIST = new HashSet<>();

    static {
        WHITE_LIST.add("/user/token");
        WHITE_LIST.add("/user/login");
        WHITE_LIST.add("/user/generate-admin");
        WHITE_LIST.add("/file/markdown/image");
        WHITE_LIST.add("/file/markdown/export");
    }

    @Autowired
    private LoginStatus loginStatus;

    private Boolean checkToken(String token) {
        return loginStatus.getTokens().contains(token);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 预检请求直接放行
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
            return;
        }

        System.out.println("token filter: " + loginStatus.toString());

        String path = request.getRequestURI();

        // 白名单路径直接放行
        if (WHITE_LIST.contains(path)) {
            filterChain.doFilter(request, response);
            return;
        }

        String token = request.getHeader("token");
        if (token == null || !checkToken(token)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json;charset=UTF-8");

            String json = objectMapper.writeValueAsString(Result.failed("Token is empty or error"));
            response.getWriter().write(json);
            return;
        }
        filterChain.doFilter(request, response);
    }
}